#ifndef AC_COMMON_PARM_STRING_H__
#define AC_COMMON_PARM_STRING_H__

#include <string>
#include <climits>

template<typename Ret> class PosibErr;

class String;

class ParmString
{
public:
    ParmString() : _str(0) {}
    ParmString(const char* str, unsigned int sz = UINT_MAX)
        : _str(str)
        , _size(sz)
    {
    }

    inline ParmString(const String&);
    inline ParmString(const PosibErr<const char *> &);
    inline ParmString(const PosibErr<String>&);

    void set(const char* str, unsigned int sz = UINT_MAX)
    {
        _str = str;
        _size = sz;
    }

    bool empty() const
    {
        return 0 == _str || '\0' == _str[0];
    }

    unsigned int size() const
    {
        if (UINT_MAX != _size)
            return _size;
        else return _size = static_cast<unsigned int>(strlen(_str));
    }

    bool have_size() const
    {
        return _size != UINT_MAX;
    }

    operator const char* () const
    {
        return _str;
    }

    const char* str() const
    {
        return _str;
    }

public:
    const char* _str;
    mutable unsigned int _size;
};

typedef const ParmString& ParmStr;

static inline bool operator == (ParmStr s1, ParmStr s2)
{
    if (s1._str == 0 || s2._str == 0)
        return s1.str() == s2.str();
    return strcmp(s1, s2) == 0;
}

static inline bool operator == (const char* s1, ParmStr s2)
{
    if (s1 == 0 || s2.str() == 0)
        return s1 == s2.str();
    return strcmp(s1, s2) == 0;
}

static inline bool operator == (ParmStr s1, const char* s2)
{
    if (s1.str() == 0 || s2 == 0)
        return s1.str() == s2;
    return strcmp(s1, s2) == 0;
}

static inline bool operator != (ParmStr s1, ParmStr s2)
{
    if (s1.str() == 0 || s2.str() == 0)
        return s1.str() != s2.str();
    return strcmp(s1, s2) != 0;
}

static inline bool operator != (const char* s1, ParmStr s2)
{
    if (s1 == 0 || s2.str() == 0)
        return s1 != s2.str();
    return strcmp(s1, s2) != 0;
}

static inline bool operator != (ParmStr s1, const char* s2)
{
    if (s1.str() == 0 || s2 == 0)
        return s1.str() != s2;
    return strcmp(s1, s2) != 0;
}

#endif  // AC_COMMON_PARM_STRING_H__
